// ds3231.c
#include "ds3231.h"
#include "utils/i2c/i2c_master/i2c_master_utils.h"
#include "esp_log.h"
#include <string.h>

// BCD转十进制
static uint8_t bcd_to_dec(uint8_t bcd) {
    return (bcd >> 4) * 10 + (bcd & 0x0F);
}

// 十进制转BCD
static uint8_t dec_to_bcd(uint8_t dec) {
    return ((dec / 10) << 4) + (dec % 10);
}

// 向DS3231写入数据
static esp_err_t ds3231_write_reg(uint8_t reg_addr, uint8_t *data, size_t len) {
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (DS3231_ADDR << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write_byte(cmd, reg_addr, true);
    i2c_master_write(cmd, data, len, true);
    i2c_master_stop(cmd);

    esp_err_t err = i2c_master_cmd_begin(I2C_MASTER_PORT_NUM, cmd, pdMS_TO_TICKS(100));
    i2c_cmd_link_delete(cmd);
    return err;
}

// 从DS3231读取数据
static esp_err_t ds3231_read_reg(uint8_t reg_addr, uint8_t *data, size_t len) {
    // 发送要读取的寄存器地址
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (DS3231_ADDR << 1) | I2C_MASTER_WRITE, true);
    i2c_master_write_byte(cmd, reg_addr, true);
    i2c_master_stop(cmd);

    esp_err_t err = i2c_master_cmd_begin(I2C_MASTER_PORT_NUM, cmd, pdMS_TO_TICKS(100));
    if (err != ESP_OK) {
        i2c_cmd_link_delete(cmd);
        return err;
    }

    // 读取数据
    cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (DS3231_ADDR << 1) | I2C_MASTER_READ, true);
    i2c_master_read(cmd, data, len, I2C_MASTER_LAST_NACK);
    i2c_master_stop(cmd);

    err = i2c_master_cmd_begin(I2C_MASTER_PORT_NUM, cmd, pdMS_TO_TICKS(100));
    i2c_cmd_link_delete(cmd);
    return err;
}

// 初始化DS3231
esp_err_t ds3231_init(void) {
    // 先初始化I2C总线
    esp_err_t err = i2c_master_init();
    if (err != ESP_OK) {
        ESP_LOGE("DS3231", "I2C initialization failed: %d", err);
        return err;
    }

    // 检查DS3231是否在线
    uint8_t status;
    err = ds3231_read_reg(DS3231_STATUS_REG, &status, 1);
    if (err != ESP_OK) {
        ESP_LOGE("DS3231", "Failed to communicate with device: %d", err);
        return err;
    }

    // 清除OSF位（振荡器停止标志）
    if (status & 0x80) {
        status &= ~0x80;
        err = ds3231_write_reg(DS3231_STATUS_REG, &status, 1);
        if (err != ESP_OK) {
            ESP_LOGE("DS3231", "Failed to clear oscillator stop flag: %d", err);
        } else {
            ESP_LOGW("DS3231", "Oscillator was stopped - time may be invalid");
        }
    }

    ESP_LOGI("DS3231", "Initialized successfully");
    return ESP_OK;
}

// 获取当前时间
esp_err_t ds3231_get_time(ds3231_time_t *time) {
    if (!time) return ESP_ERR_INVALID_ARG;

    uint8_t data[7];
    esp_err_t err = ds3231_read_reg(DS3231_TIME_REG, data, 7);
    if (err != ESP_OK) {
        ESP_LOGE("DS3231", "Failed to read time: %d", err);
        return err;
    }

    // 解析时间数据
    time->seconds = bcd_to_dec(data[0] & 0x7F);
    time->minutes = bcd_to_dec(data[1]);

    // 小时数据需判断12/24小时制
    if (data[2] & 0x40) {
        // 12小时制
        time->hours = bcd_to_dec(data[2] & 0x1F);
        time->is_pm = (data[2] & 0x20) != 0;
    } else {
        // 24小时制
        time->hours = bcd_to_dec(data[2] & 0x3F);
        time->is_pm = false;
    }

    time->day = bcd_to_dec(data[3]);
    time->date = bcd_to_dec(data[4]);
    time->month = bcd_to_dec(data[5] & 0x1F);
    time->year = bcd_to_dec(data[6]);

    return ESP_OK;
}

// 设置当前时间
esp_err_t ds3231_set_time(ds3231_time_t *time) {
    if (!time) return ESP_ERR_INVALID_ARG;

    uint8_t data[7];

    // 构建时间数据（BCD格式）
    data[0] = dec_to_bcd(time->seconds);
    data[1] = dec_to_bcd(time->minutes);

    // 设置小时（24小时制）
    data[2] = dec_to_bcd(time->hours);

    data[3] = dec_to_bcd(time->day);
    data[4] = dec_to_bcd(time->date);
    data[5] = dec_to_bcd(time->month);
    data[6] = dec_to_bcd(time->year);

    // 写入时间
    esp_err_t err = ds3231_write_reg(DS3231_TIME_REG, data, 7);
    if (err != ESP_OK) {
        ESP_LOGE("DS3231", "Failed to set time: %d", err);
    }

    return err;
}

// 获取温度
esp_err_t ds3231_get_temperature(float *temp) {
    if (!temp) return ESP_ERR_INVALID_ARG;

    uint8_t data[2];
    esp_err_t err = ds3231_read_reg(DS3231_TEMP_REG, data, 2);
    if (err != ESP_OK) {
        ESP_LOGE("DS3231", "Failed to read temperature: %d", err);
        return err;
    }

    // 计算温度值（高8位 + 低2位的0.25精度）
    *temp = (float)data[0] + (float)((data[1] >> 6) * 0.25);
    return ESP_OK;
}
#include <time.h>

// 时间戳转RTC格式
esp_err_t ds3231_set_time_from_timestamp(time_t timestamp) {
    struct tm *tm_info;
    ds3231_time_t rtc_time;

    // 将时间戳转换为本地时间
    tm_info = localtime(&timestamp);

    // 填充RTC时间结构
    rtc_time.seconds = tm_info->tm_sec;
    rtc_time.minutes = tm_info->tm_min;
    rtc_time.hours = tm_info->tm_hour;
    rtc_time.day = tm_info->tm_wday + 1;  // tm_wday范围0-6 (周日为0)，DS3231范围1-7
    rtc_time.date = tm_info->tm_mday;
    rtc_time.month = tm_info->tm_mon + 1; // tm_mon范围0-11
    rtc_time.year = tm_info->tm_year - 100; // tm_year是从1900开始的年数

    return ds3231_set_time(&rtc_time);
}

// RTC格式转时间戳
esp_err_t ds3231_get_timestamp(time_t *timestamp) {
    if (!timestamp) return ESP_ERR_INVALID_ARG;

    ds3231_time_t rtc_time;
    esp_err_t err = ds3231_get_time(&rtc_time);
    if (err != ESP_OK) {
        return err;
    }

    // 填充tm结构
    struct tm tm_info = {
            .tm_sec = rtc_time.seconds,
            .tm_min = rtc_time.minutes,
            .tm_hour = rtc_time.hours,
            .tm_mday = rtc_time.date,
            .tm_mon = rtc_time.month - 1,
            .tm_year = rtc_time.year + 100, // 转换为从1900开始的年数
            .tm_wday = rtc_time.day - 1,   // 转换为0-6 (周日为0)
    };

    // 转换为时间戳
    *timestamp = mktime(&tm_info);
    return ESP_OK;
}